/**
 * create by zhangpu
 * date:2015年3月12日
 */
package com.acooly.module.openapi.client.provider.fuiou.marshall;

import com.acooly.core.utils.Strings;
import com.acooly.module.openapi.client.api.exception.ApiClientException;
import com.acooly.module.openapi.client.api.marshal.ApiUnmarshal;
import com.acooly.module.openapi.client.api.message.MessageFactory;
import com.acooly.module.openapi.client.api.util.XStreams;
import com.acooly.module.openapi.client.provider.fuiou.FuiouConstants;
import com.acooly.module.openapi.client.provider.fuiou.domain.FuiouResponse;
import com.acooly.module.openapi.client.provider.fuiou.support.FuiouRespCodes;
import com.thoughtworks.xstream.XStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author zhangpu
 */
@Service
public class FuiouResponseUnmarshall extends FuiouMarshallSupport implements ApiUnmarshal<FuiouResponse, String> {

    private static final Logger logger = LoggerFactory.getLogger(FuiouResponseUnmarshall.class);

    @Resource(name = "fuiouMessageFactory")
    private MessageFactory messageFactory;


    @SuppressWarnings("unchecked")
    @Override
    public FuiouResponse unmarshal(String message, String serviceName) {
        try {
            logger.info("响应报文:{}", Strings.substringAfter(message, "?>"));
            String plain = message.substring(message.indexOf("<plain>"), message.indexOf("<signature>"));
            String signature = Strings.substringAfter(message, "<signature>");
            signature = Strings.substringBeforeLast(signature, "</signature>");
            getSignerFactory().getSigner(FuiouConstants.SIGNER_KEY).verify(signature, getKeyPair(), plain);
            return doUnmarshall(plain, serviceName);
        } catch (Exception e) {
            throw new ApiClientException("解析响应报文错误:" + e.getMessage());
        }
    }

    protected FuiouResponse doUnmarshall(String xml, String serviceName) {
        FuiouResponse response = (FuiouResponse) messageFactory.getResponse(serviceName);
        XStream xstream = XStreams.getXStream();
        xstream.alias("plain", response.getClass());
        response = (FuiouResponse) xstream.fromXML(xml, response);
        response.setService(serviceName);
        response.setMessage(FuiouRespCodes.getMessage(response.getRespCode()));
        return response;
    }

    public void setMessageFactory(MessageFactory messageFactory) {
        this.messageFactory = messageFactory;
    }

}
